﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using AzukiMap.Map;
using Geotools.Geometries;
using AzukiMap.Tools.Logger;
using System.Windows.Media.Imaging;

namespace AzukiMap.Renderer
{
    public class RasterRenderer
    {
        const int DEFAULT_RASTER_WIDTH = 100;
        const int DEFAULT_RASTER_HEIGHT = 100;

        enum ImagePosition
        {
            TOP_LEFT,
            BOTTOM_RIGHT
        }

        MapCanvas _mapCanvas;

        public RasterRenderer(MapCanvas mapCanvas)
        {
            _mapCanvas = mapCanvas;
        }

        public void DrawRaster(int id, GTPolygon imageExtent, string imageUriString, bool isClockWise )
        {
            DrawRaster(id, imageExtent, new Uri(imageUriString), isClockWise);
        }

        public void DrawRaster(int id, GTPolygon imageExtent, string imageUriString )
        {
            DrawRaster(id, imageExtent, new Uri(imageUriString));
        }

        public void DrawRaster(int id, GTPolygon imageExtent, Uri imageUri, bool isClockWise ) {
            GTCoordinates coords = imageExtent.GetCoordinates();

            // the extent should have 4 points.
            if (coords.Count < 4)
            {
                Logger.Warn("AzukiMap.Renderer.RasterRenderer.DrawRaster: imageExtent should have 4 points");
                return;
            }

            ImageTriangle imageTl = CreateImageTriangle(coords, imageUri, ImagePosition.TOP_LEFT, isClockWise);
            ImageTriangle imageBr = CreateImageTriangle(coords, imageUri, ImagePosition.BOTTOM_RIGHT, isClockWise);

            _mapCanvas.Children.Add(imageTl);
            _mapCanvas.Children.Add(imageBr);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <param name="imageExtent">A image extent by a polygon. This should be clock wise and used only 4 points.</param>
        /// <param name="imageUri"></param>
        public void DrawRaster(int id, GTPolygon imageExtent, Uri imageUri )
        {
            DrawRaster(id, imageExtent, imageUri, true);
        }

        ImageTriangle CreateImageTriangle(GTCoordinates coords, Uri imageUri, ImagePosition pos, bool isClockWise)
        {
            ImageTriangle imageTriangle = new ImageTriangle();
            ImageSource source = new BitmapImage(imageUri);
            imageTriangle.TextureSource = source;
            if (pos == ImagePosition.TOP_LEFT)
            {
                // top left
                imageTriangle.Point1 = GetPixPoint(coords[0]);
                // top right
                if ( isClockWise ) 
                    imageTriangle.Point2 = GetPixPoint(coords[1]);
                else
                    imageTriangle.Point2 = GetPixPoint(coords[3]);
                // bottom left
                if ( isClockWise ) 
                    imageTriangle.Point3 = GetPixPoint(coords[3]);
                else
                    imageTriangle.Point3 = GetPixPoint(coords[1]);

                // set positions
                PointCollection pc = new PointCollection();
                // top left
                pc.Add(new Point(0, 0));
                // top right
                pc.Add(new Point(1, 0));
                // bottom left
                pc.Add(new Point(0, 1));
                imageTriangle.TexturePositions = pc;
            }
            else
            {
                // top right 
                if ( isClockWise ) 
                    imageTriangle.Point1 = GetPixPoint(coords[1]);
                else
                    imageTriangle.Point1 = GetPixPoint(coords[3]);
                // bottom left 
                if ( isClockWise )
                    imageTriangle.Point2 = GetPixPoint(coords[3]);
                else
                    imageTriangle.Point2 = GetPixPoint(coords[1]);
                // bottom right 
                imageTriangle.Point3 = GetPixPoint(coords[2]);

                // set positions
                PointCollection pc = new PointCollection();
                // top right 
                pc.Add(new Point(1, 0));
                // bottom left 
                pc.Add(new Point(0, 1));
                // bottom right 
                pc.Add(new Point(1, 1));
                imageTriangle.TexturePositions = pc;
            }

            return imageTriangle;
        }

        Point GetPixPoint(GTCoordinate coord)
        {
            GTPoint pixPoint = _mapCanvas.GetPixPointFromGeo(coord.X, coord.Y);
            Point p = new Point(pixPoint.X, pixPoint.Y);

            return p;
        }

    }
    
}
